home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
os2
/
radius_2.zip
/
users.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-28
|
12KB
|
560 lines
/*
*
* RADIUS
* Remote Authentication Dial In User Service
*
*
* Livingston Enterprises, Inc.
* 6920 Koll Center Parkway
* Pleasanton, CA 94566
*
* Copyright 1992 Livingston Enterprises, Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose and without fee is hereby granted, provided that this
* copyright and permission notice appear on all copies and supporting
* documentation, the name of Livingston Enterprises, Inc. not be used
* in advertising or publicity pertaining to distribution of the
* program without specific prior permission, and notice be given
* in supporting documentation that copying and distribution is by
* permission of Livingston Enterprises, Inc.
*
* Livingston Enterprises, Inc. makes no representations about
* the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
*/
static char sccsid[] =
"@(#)users.c 1.12 Copyright 1992 Livingston Enterprises Inc";
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <pwd.h>
#include <time.h>
#include <ctype.h>
#include "radius.h"
#ifdef DBM
#include <dbm.h>
#endif /* DBM */
extern char *progname;
extern int debug_flag;
extern char *radius_dir;
static void fieldcpy();
static int userparse();
#define FIND_MODE_NAME 0
#define FIND_MODE_REPLY 1
#define FIND_MODE_SKIP 2
#define FIND_MODE_FLUSH 3
void user_gettime(char *valstr,struct tm *tm);
/*************************************************************************
*
* Function: user_find
*
* Purpose: Find the named user in the database. Create the
* set of attribute-value pairs to check and reply with
* for this user from the database.
*
*************************************************************************/
int
user_find(name, check_pairs, reply_pairs)
char *name;
VALUE_PAIR **check_pairs;
VALUE_PAIR **reply_pairs;
{
FILE *userfd;
char buffer[256];
char msg[128];
char *ptr;
int namelen;
int mode;
VALUE_PAIR *check_first;
VALUE_PAIR *reply_first;
#ifdef DBM
datum named;
datum contentd;
#endif /* DBM */
/*
* Check for valid input, zero length names not permitted
*/
userfd = NULL;
mode = FIND_MODE_NAME;
ptr=name;
while (*ptr != '\0') {
if (*ptr == ' ' || *ptr == '\t') {
*ptr = '\0';
} else {
ptr++;
}
}
namelen=strlen(name);
if (namelen < 1) {
fprintf(stderr, "%s: zero length username not permitted\n",progname);
return(-1);
}
/*
* Open the user table
*/
sprintf(buffer, "%s/%s", radius_dir, RADIUS_USERS);
#ifdef DBM
if(dbminit(buffer) != 0) {
#else /* DBM */
if((userfd = fopen(buffer, "r")) == (FILE *)NULL) {
#endif /* DBM */
fprintf(stderr, "%s:Couldn't open %s for reading\n",
progname, buffer);
return(-1);
}
check_first = (VALUE_PAIR *)NULL;
reply_first = (VALUE_PAIR *)NULL;
#ifdef DBM
named.dptr = name;
named.dsize = strlen(name);
contentd = fetch(named);
if(contentd.dsize == 0) {
named.dptr = "DEFAULT";
named.dsize = strlen("DEFAULT");
contentd = fetch(named);
if(contentd.dsize == 0) {
dbmclose();
return(-1);
}
}
/*
* Parse the check values
*/
ptr = contentd.dptr;
contentd.dptr[contentd.dsize] = '\0';
if(userparse(ptr, &check_first) != 0) {
sprintf(msg, "%s: Parse error for user %s\n",
progname, name);
fprintf(stderr, msg);
log_err(msg);
pairfree(check_first);
dbmclose();
return(-1);
}
while(*ptr != '\n' && *ptr != '\0') {
ptr++;
}
if(*ptr != '\n') {
pairfree(check_first);
dbmclose();
return(-1);
}
ptr++;
/*
* Parse the reply values
*/
if(userparse(ptr, &reply_first) != 0) {
fprintf(stderr, "%s: Parse error for user %s\n",
progname, name);
pairfree(check_first);
pairfree(reply_first);
dbmclose();
return(-1);
}
dbmclose();
#else /* DBM */
while(fgets(buffer, sizeof(buffer), userfd) != (char *)NULL) {
if(mode == FIND_MODE_NAME) {
/*
* Find the entry starting with the users name
*/
if((strncmp(buffer, name, namelen) == 0 &&
(buffer[namelen] == ' ' || buffer[namelen] == '\t')) ||
strncmp(buffer, "DEFAULT", 7) == 0) {
if(strncmp(buffer, "DEFAULT", 7) == 0) {
ptr = &buffer[7];
}
else {
ptr = &buffer[namelen];
}
/*
* Parse the check values
*/
if(userparse(ptr, &check_first) != 0) {
sprintf(msg,"%s: Parse error for user %s\n",
progname, name);
fprintf(stderr,msg);
log_err(msg);
pairfree(check_first);
fclose(userfd);
return(-1);
}
mode = FIND_MODE_REPLY;
}
}
else {
if(*buffer == ' ' || *buffer == '\t') {
/*
* Parse the reply values
*/
if(userparse(buffer, &reply_first) != 0) {
fprintf(stderr,
"%s: Parse error for user %s\n",
progname, name);
pairfree(check_first);
pairfree(reply_first);
fclose(userfd);
return(-1);
}
}
else {
/* We are done */
fclose(userfd);
*check_pairs = check_first;
*reply_pairs = reply_first;
return(0);
}
}
}
fclose(userfd);
#endif /* DBM */
/* Update the callers pointers */
if(reply_first != (VALUE_PAIR *)NULL) {
*check_pairs = check_first;
*reply_pairs = reply_first;
return(0);
}
return(-1);
}
#define PARSE_MODE_NAME 0
#define PARSE_MODE_EQUAL 1
#define PARSE_MODE_VALUE 2
#define PARSE_MODE_INVALID 3
/*************************************************************************
*
* Function: userparse
*
* Purpose: Parses the buffer to extract the attribute-value pairs.
*
*************************************************************************/
static int
userparse(buffer, first_pair)
char *buffer;
VALUE_PAIR **first_pair;
{
int mode;
char attrstr[64];
char valstr[64];
DICT_ATTR *attr;
DICT_ATTR *dict_attrfind();
DICT_VALUE *dval;
DICT_VALUE *dict_valfind();
VALUE_PAIR *pair;
VALUE_PAIR *link;
UINT4 ipstr2long();
UINT4 get_ipaddr();
struct tm *tm;
time_t timeval;
mode = PARSE_MODE_NAME;
while(*buffer != '\n' && *buffer != '\0') {
if(*buffer == ' ' || *buffer == '\t' || *buffer == ',') {
buffer++;
continue;
}
switch(mode) {
case PARSE_MODE_NAME:
/* Attribute Name */
fieldcpy(attrstr, &buffer);
if((attr = dict_attrfind(attrstr)) ==
(DICT_ATTR *)NULL) {
return(-1);
}
mode = PARSE_MODE_EQUAL;
break;
case PARSE_MODE_EQUAL:
/* Equal sign */
if(*buffer == '=') {
mode = PARSE_MODE_VALUE;
buffer++;
}
else {
return(-1);
}
break;
case PARSE_MODE_VALUE:
/* Value */
fieldcpy(valstr, &buffer);
if((pair = (VALUE_PAIR *)malloc(sizeof(VALUE_PAIR))) ==
(VALUE_PAIR *)NULL) {
fprintf(stderr, "%s: no memory\n",
progname);
exit(-1);
}
strcpy(pair->name, attr->name);
pair->attribute = attr->value;
pair->type = attr->type;
switch(pair->type) {
case PW_TYPE_STRING:
strcpy(pair->strvalue, valstr);
break;
case PW_TYPE_INTEGER:
if(isdigit(*valstr)) {
pair->lvalue = atoi(valstr);
}
else if((dval = dict_valfind(valstr)) ==
(DICT_VALUE *)NULL) {
free(pair);
return(-1);
}
else {
pair->lvalue = dval->value;
}
break;
case PW_TYPE_IPADDR:
pair->lvalue = get_ipaddr(valstr);
break;
case PW_TYPE_DATE:
timeval = time(0);
tm = localtime(&timeval);
user_gettime(valstr, tm);
#ifdef TIMELOCAL
pair->lvalue = (UINT4)timelocal(tm);
#else /* TIMELOCAL */
pair->lvalue = (UINT4)mktime(tm);
#endif /* TIMELOCAL */
break;
default:
free(pair);
return(-1);
}
pair->next = (VALUE_PAIR *)NULL;
if(*first_pair == (VALUE_PAIR *)NULL) {
*first_pair = pair;
}
else {
link = *f